package cn.stylefeng.guns.modular.rest.agv;

import cn.hutool.core.collection.ListUtil;
import cn.stylefeng.guns.modular.agv.entity.AgvStorageTask;
import cn.stylefeng.guns.modular.agv.entity.AgvStorageTaskDetail;
import cn.stylefeng.guns.modular.agv.model.params.CreateSortParam;
import cn.stylefeng.guns.modular.agv.model.params.HikAgvTaskParam;
import cn.stylefeng.guns.modular.agv.model.params.TargetActionsVo;
import cn.stylefeng.guns.modular.agv.service.AgvStorageTaskDetailService;
import cn.stylefeng.guns.modular.agv.service.AgvStorageTaskService;
import cn.stylefeng.guns.modular.agv.util.HikApiUtils;
import cn.stylefeng.guns.modular.agv.util.HikRsVo;
import cn.stylefeng.guns.modular.agv.util.TuskRsVo;
import cn.stylefeng.guns.modular.agv.util.TustApiUtils;
import cn.stylefeng.guns.modular.hx.storage.entity.HxStorageOut;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOutParam;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOutService;
import cn.stylefeng.guns.modular.rest.agv.vo.StorageOutCntOby;
import cn.stylefeng.guns.modular.rest.agv.vo.SueTaskIby;
import cn.stylefeng.guns.modular.rest.aop.UserAop;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.List;

/**
 * 地址控制器
 */
@Controller
@RequestMapping("/rest/agvStorageScan")
public class RestAgvStorageScanController extends BaseController {

    @Autowired
    private UserAop userAop;

    @Autowired
    private AgvStorageTaskService agvStorageTaskService;

    @Autowired
    private AgvStorageTaskDetailService agvStorageTaskDetailService;


    @Autowired
    private HxStorageOutService hxStorageOutService;

    /**
     * 新增接口
     *
     * @author zhangzh
     * @Date 2024-05-14
     */
    @RequestMapping("/areaStorageOutCntList")
    @ResponseBody
    public List<StorageOutCntOby> areaStorageOutCntList() {
        User user = userAop.getUser();
        HxStorageOutParam hxStorageOutParam = new HxStorageOutParam();
        hxStorageOutParam.setDeptId(user.getDeptId());
        if (ToolUtil.isNotEmpty(user.getOperateId())) {
            hxStorageOutParam.setOperateId(user.getOperateId());
        }
        return hxStorageOutService.areaStorageOutCntList(hxStorageOutParam);
    }


    /**
     * 下发任务
     * @param sueTaskIby
     * @return
     */
    @RequestMapping("/issueTask")
    @ResponseBody
    public ResponseData issueTask(SueTaskIby sueTaskIby) {
        User user = userAop.getUser();
        return hxStorageOutService.issueTask(sueTaskIby, user);
    }

    /**
     * 扫AGV编号，领取对应的拣货任务
     * @param agvNo
     * @return
     */
    @RequestMapping("/scanAgv")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class, timeout = 180)
    public ResponseData scanAgv(String agvNo) {
        User user = userAop.getUser();

        if(ToolUtil.isEmpty(agvNo)){
            return ResponseData.error("未获取到机器人编号，请重新扫码获取");
        }

        //根据机器人编号，获取已下发，未领取的任务
        List<AgvStorageTask> agvStorageTaskList = this.agvStorageTaskService.lambdaQuery()
                .eq(AgvStorageTask::getAgvNo, agvNo)
//                .eq(AgvStorageTask::getStat,"00")
                .in(AgvStorageTask::getStat, ListUtil.of("00","10"))
                .list();
        if(ToolUtil.isEmpty(agvStorageTaskList)){
            return ResponseData.error("AGV未绑定拣货任务，请稍后操作");
        }

        if(agvStorageTaskList.size() > 1){
            return ResponseData.error("AGV["+agvNo+"]同时绑定了"+agvStorageTaskList.size()+"个拣货任务，请取消其他任务后重试！");
        }
        AgvStorageTask agvStorageTask = agvStorageTaskList.get(0);
        //获取对应的拣货ID
        List<HxStorageOut> hxStorageOutList = this.hxStorageOutService.lambdaQuery()
                .eq(HxStorageOut::getStorageNumber, agvStorageTask.getStorageNumber())
                .list();
        if(ToolUtil.isEmpty(hxStorageOutList)){
            return ResponseData.error("AGV绑定的拣货任务不存在");
        }else if("10".equals(agvStorageTask.getStat())){
            // 如果拣货中，则直接跳转
            return ResponseData.success(hxStorageOutList.get(0).getId());
        }
        //扫码成功后，小车移动到第一个拣货位
        AgvStorageTaskDetail agvStorageTaskDetail = agvStorageTaskDetailService.lambdaQuery()
                .eq(AgvStorageTaskDetail::getStorageTaskId, agvStorageTask.getId())
                .last(" order by position_pickingorder limit 1 ")
                .one();

        //如果是海康机器人
        if ("HIK".equals(agvStorageTask.getAgvTyp())) {
            //封装接口信息
            HikAgvTaskParam param = new HikAgvTaskParam();
            param.setTaskNo(agvStorageTask.getTaskNo());
            param.setPositionType("2");
            param.setEndcargoInfo(agvStorageTaskDetail.getPositionNumber());
            HikRsVo hikRsVo = HikApiUtils.genctnrBinTask(agvStorageTask.getAgvApiBaseUrl(), param);
            if (hikRsVo == null) {
                return ResponseData.error("接口调用错误");
            } else if (!"0".equals(hikRsVo.getCode())) {
                return ResponseData.error(hikRsVo.getMessage());
            }
        } else if ("TUSK".equals(agvStorageTask.getAgvTyp())) {
            CreateSortParam param = new CreateSortParam();
            param.setTaskId(agvStorageTask.getTaskNo());
            //取货点
            param.getTargetActions().add(TargetActionsVo.builder()
                    .target(agvStorageTaskDetail.getPositionNumber())
                    .action("MOVE")
                    .build());
            TuskRsVo tuskRs = TustApiUtils.createSortTask(agvStorageTask.getAgvApiBaseUrl(), param);
            if (tuskRs == null) {
                return ResponseData.error("接口调用错误");
            } else if (tuskRs.getCode() != 200) {
                return ResponseData.error(tuskRs.getMsg());
            }
        }
        //绑定拣货人
        this.hxStorageOutService.lambdaUpdate()
                .eq(HxStorageOut::getId,hxStorageOutList.get(0).getId())
                .set(HxStorageOut::getStorageUser,user.getAccount())
                .set(HxStorageOut::getStorageUserName,user.getName())
                .set(HxStorageOut::getStorageTime,new Date())
                .update();
        //修改拣货任务为拣货中
        agvStorageTaskService.lambdaUpdate()
                .eq(AgvStorageTask::getId,agvStorageTask.getId())
                .set(AgvStorageTask::getStat,"10")
                .update();

        return ResponseData.success(hxStorageOutList.get(0).getId());
    }
}
